package com.java1234.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author 邓清文
 * @version 1.0
 * @description:
 * @since 2024/12/17 9:26
 */
@ServerEndpoint("/websocket/{userId}")
@Component
@Slf4j
public class WebSocketServer {
    /**
     * 建立连接的用户ConcurrentHashMap线程安全
     */
    private static final Map<String, Session> ONLINE_USERS = new ConcurrentHashMap<>();
    @OnOpen
    public void onOpen(Session session, @PathParam("userId") String userId){
        //放入建立连接的用户
        ONLINE_USERS.put(userId,session);
        log.info("用户：{} 开启WebSocket连接成功！在线人数：{}",userId,ONLINE_USERS.size());
    }

    @OnClose
    public void onClose(Session session){
        remove(session);
    }

    @OnMessage
    public void onMessage(Session session ,String message){
        log.info("收到客户端消息：{}",message);
        //消息发送给指定的session
//        session.getAsyncRemote().sendText(message);
        sendMessage(message,session);
        log.info("消息发送成功,消息：{}",message);

    }

    public void sendMessage(String message){
        ONLINE_USERS.forEach((userId,session)->{
            //发送消息给每一个session在线用户
            this.sendMessage(session,message);
        });
    }


    //通过session群发消息，排除自己
    public void sendMessage(String message,Session mysession){
        ONLINE_USERS.forEach((userId,session)->{
            //排除自己
            if(!mysession.equals(session)){
                //发送消息给每一个session在线用户
                this.sendMessage(session,message);
            }
        });
    }
    //通过userid群发消息，排除自己
    public void sendMessage(String message,String myuserId){
        Session mysession = getsession(myuserId);
        ONLINE_USERS.forEach((userId,session)->{
            //排除自己
            if(!mysession.equals(session)){
                //发送消息给每一个session在线用户
                this.sendMessage(session,message);
            }
        });
    }


    /**
     * 根据userId向指定用户发送消息
     *
     * @param userId  用户ID
     * @param message 要发送的消息
     */
    public void sendMessageToUser(String userId, String message) {
        Session session = getsession(userId);
        if (session != null && session.isOpen()) {
            session.getAsyncRemote().sendText(message);
            log.info("消息发送成功, 用户ID：{}, 消息：{}", userId, message);
        } else {
            log.error("用户：{} 不在线或会话已关闭", userId);
        }
    }

    //通过userId获取session
    public  Session getsession(String userId){
        Session session = ONLINE_USERS.get(userId);
        return session;
    }


    public  void sendMessage(Session session,String message) {
        if(session!=null&&session.isOpen()) {
            session.getAsyncRemote().sendText(message);
        }
    }

    @OnError
    public void onError(Session session, Throwable error) throws IOException {
        log.error("WebSocket连接出错，消息：{}",error.getMessage(),error);
        if(session.isOpen()){
            session.close();
        }
        //移除map中出错的session
        remove(session);
    }

    public void remove(Session session){
        String userId = null;
        //通过session获取用户id，通过Map中的value获取key，map中的key和value都是唯一的
        for(Map.Entry<String,Session> entry:ONLINE_USERS.entrySet()){
            if(entry.getValue().equals(session)){
                userId = entry.getKey();
                break;
            }
        }
        if(userId!=null){
            ONLINE_USERS.remove(userId);
            log.info("用户：{} 关闭WebSocket连接！在线人数：{}",userId,ONLINE_USERS.size());
        }else{
            log.error("关闭WebSocket连接失败");
        }
        log.info("WebSocket连接关闭");
    }
}
